package main

import "fmt"

// go语言中return不是原子操作,底层分为两步:
// 1、返回值赋值
// 2、 真正的返回
// 函数中如果有defer,defer执行时机在第一步和第二步之间

// 顺序:
// 1、 返回值复制
// 2、 defer
// 3、 执行return
func f1() int {
	x := 5
	defer func() {
		x++		// 修改的不是返回值
	}()
	return x
}

func f2() (x int) {
	defer func() {
		x++
	}()
	return 5	// 这个5就是返回值x,所以在真正执行return时候执行了x++
}
func f3() (y int) {
	x := 5
	defer func() {
		x++
	}()
	return x	// 返回值是y,但是返回的是x,x是5
}
func f4() (x int) {
	defer func(x int) {
		x++		// 改变的是函数中的副本,不是外面函数f4的x
	}(x)
	return 5
}
func main() {
	fmt.Println(f1()) // 5
	fmt.Println(f2()) // 6
	fmt.Println(f3()) // 5
	fmt.Println(f4()) // 5
}
